/*
 * Copyright (c) 2023 iQi.Co.Ltd. All rights reserved.
 */
 
using System.Collections.Generic;
using NetProtocol.POD;
using NetProtocol.Enum;
using IQIGame.Onigao.Game;
using IQIGame.Onigao.GamePlay;
using IQIGame.Onigao.Framework;
using Cysharp.Threading.Tasks;
using System;
using static IQIGame.Onigao.Game.MessageWrapper;

namespace NetProtocol.Client {
	/// <summary>
	/// 邮件模块
	/// module : mail
	/// </summary>
	public interface CNetMail : INetClientModule {
		
		public ISession GetSession();
	
		Dictionary<int, INetClientModule.Package2MessageWrapper> INetClientModule.GetModuleFunction()
        {
            MessageFunction getMailsResult_Delegate = (session, wrapper) =>
            {
            	var _wrapper = (MessageWrapper<GetMailsResultData>)wrapper;
                SC_getMailsResult(session, ref _wrapper.message);
                MessageWrapperPool<GetMailsResultData>.Put(_wrapper);
            };
            MessageFunction readMailResult_Delegate = (session, wrapper) =>
            {
            	var _wrapper = (MessageWrapper<ReadMailResultData>)wrapper;
                SC_readMailResult(session, ref _wrapper.message);
                MessageWrapperPool<ReadMailResultData>.Put(_wrapper);
            };
            MessageFunction pickUpResult_Delegate = (session, wrapper) =>
            {
            	var _wrapper = (MessageWrapper<PickUpResultData>)wrapper;
                SC_pickUpResult(session, ref _wrapper.message);
                MessageWrapperPool<PickUpResultData>.Put(_wrapper);
            };
            MessageFunction deleteMailResult_Delegate = (session, wrapper) =>
            {
            	var _wrapper = (MessageWrapper<DeleteMailResultData>)wrapper;
                SC_deleteMailResult(session, ref _wrapper.message);
                MessageWrapperPool<DeleteMailResultData>.Put(_wrapper);
            };
            MessageFunction notifyNewMail_Delegate = (session, wrapper) =>
            {
            var _wrapper = (MessageWrapper<NotifyNewMailData>)wrapper; 
#if ENABLE_NET_LOG || UNITY_EDITOR
            NetProtocolHelper.ClientLog(NetMessageId.mail_notifyNewMail, "Recv->" + _wrapper.message.ToString());
#endif
                SC_notifyNewMail(session, _wrapper.message.newMailCount);
                MessageWrapperPool<NotifyNewMailData>.Put(_wrapper);
            };
        
            Dictionary<int, INetClientModule.Package2MessageWrapper> retDic = new()
            {
                {NetMessageId.mail_getMailsResult, (session, package) => {
                	var result = MessageWrapperPool<GetMailsResultData>.Get();
                	result.Init(session, getMailsResult_Delegate);
                	result.FromPackage(package);
                	return result;
                }},
                {NetMessageId.mail_readMailResult, (session, package) => {
                	var result = MessageWrapperPool<ReadMailResultData>.Get();
                	result.Init(session, readMailResult_Delegate);
                	result.FromPackage(package);
                	return result;
                }},
                {NetMessageId.mail_pickUpResult, (session, package) => {
                	var result = MessageWrapperPool<PickUpResultData>.Get();
                	result.Init(session, pickUpResult_Delegate);
                	result.FromPackage(package);
                	return result;
                }},
                {NetMessageId.mail_deleteMailResult, (session, package) => {
                	var result = MessageWrapperPool<DeleteMailResultData>.Get();
                	result.Init(session, deleteMailResult_Delegate);
                	result.FromPackage(package);
                	return result;
                }},
                {NetMessageId.mail_notifyNewMail, (session, package) => {
                	var result = MessageWrapperPool<NotifyNewMailData>.Get();
                	result.Init(session, notifyNewMail_Delegate);
                	result.FromPackage(package);
                	return result;
                }},
            };
            return retDic;
        }
#region Client-side Interface
		/// <summary>
        /// 
        /// </summary>
		public void SC_getMailsResult(ISession session, ref GetMailsResultData message) 
		{
            _SC_getMailsResult(session, ref message);
		}
		
		public void _SC_getMailsResult(ISession session, ref GetMailsResultData message)
		{
#if ENABLE_NET_LOG || UNITY_EDITOR
            NetProtocolHelper.ClientLog(NetMessageId.mail_getMailsResult, "Recv->" + message.ToString());
#endif
			NetProtocolHelper.endCallRequest?.Invoke(NetMessageId.mail_getMailsResult, message.code);
			MsgAsyncAwaiter<GetMailsResultData>.Instance.CompleteMsgAwait(ref message);
		}
		
		/// <summary>
        /// 
        /// </summary>
		public void SC_readMailResult(ISession session, ref ReadMailResultData message) 
		{
            _SC_readMailResult(session, ref message);
		}
		
		public void _SC_readMailResult(ISession session, ref ReadMailResultData message)
		{
#if ENABLE_NET_LOG || UNITY_EDITOR
            NetProtocolHelper.ClientLog(NetMessageId.mail_readMailResult, "Recv->" + message.ToString());
#endif
			NetProtocolHelper.endCallRequest?.Invoke(NetMessageId.mail_readMailResult, message.code);
			MsgAsyncAwaiter<ReadMailResultData>.Instance.CompleteMsgAwait(ref message);
		}
		
		/// <summary>
        /// getItems=获得的物品
        /// </summary>
		public void SC_pickUpResult(ISession session, ref PickUpResultData message) 
		{
            _SC_pickUpResult(session, ref message);
		}
		
		public void _SC_pickUpResult(ISession session, ref PickUpResultData message)
		{
#if ENABLE_NET_LOG || UNITY_EDITOR
            NetProtocolHelper.ClientLog(NetMessageId.mail_pickUpResult, "Recv->" + message.ToString());
#endif
			NetProtocolHelper.endCallRequest?.Invoke(NetMessageId.mail_pickUpResult, message.code);
			MsgAsyncAwaiter<PickUpResultData>.Instance.CompleteMsgAwait(ref message);
		}
		
		/// <summary>
        /// 
        /// </summary>
		public void SC_deleteMailResult(ISession session, ref DeleteMailResultData message) 
		{
            _SC_deleteMailResult(session, ref message);
		}
		
		public void _SC_deleteMailResult(ISession session, ref DeleteMailResultData message)
		{
#if ENABLE_NET_LOG || UNITY_EDITOR
            NetProtocolHelper.ClientLog(NetMessageId.mail_deleteMailResult, "Recv->" + message.ToString());
#endif
			NetProtocolHelper.endCallRequest?.Invoke(NetMessageId.mail_deleteMailResult, message.code);
			MsgAsyncAwaiter<DeleteMailResultData>.Instance.CompleteMsgAwait(ref message);
		}
		
		/// <summary>
        /// 通知新邮件数量(普通邮件)
        /// </summary>
		protected void SC_notifyNewMail(ISession session, int newMailCount);
#endregion
#region Server-side Interface
		/// <summary>
        /// 得到邮件列表
        /// </summary>
    	public UniTask<GetMailsResultData> CS_getMails(int mailType)
        {
            return _CS_getMails(mailType);
        }
        
        public UniTask<GetMailsResultData> _CS_getMails(int mailType)
        {
        	ISession session = GetSession();
        	if(session == null) return UniTask.FromResult(default(GetMailsResultData));
#if ENABLE_NET_LOG || UNITY_EDITOR
			NetProtocolHelper.ClientLog(NetMessageId.mail_getMails, "Send->"+"Mail.CS_getMails { "
				+ "mailType="
				+ mailType
				+" }");
#endif
        	UniTask<GetMailsResultData> task = MsgAsyncAwaiter<GetMailsResultData>.Instance.AddMsgAwait();
        	session.SendPack(Pack_for_getMails(mailType));
        	NetProtocolHelper.beginCallRequest?.Invoke(NetMessageId.mail_getMailsResult);
			return task;
        }
		
		public static SendPackage Pack_for_getMails(int mailType) 
		{
			SendPackage si_p = NetProtocolHelper.GetSendPackage();
			si_p.Header.Messagid = NetMessageId.mail_getMails;
			si_p.StartWrite();
			SOutputStream _out = si_p.OutputStream;
			_out.Write_int(mailType);
			return si_p;
		}
		/// <summary>
        /// 阅读邮件
        /// </summary>
    	public UniTask<ReadMailResultData> CS_readMail(long mailId)
        {
            return _CS_readMail(mailId);
        }
        
        public UniTask<ReadMailResultData> _CS_readMail(long mailId)
        {
        	ISession session = GetSession();
        	if(session == null) return UniTask.FromResult(default(ReadMailResultData));
#if ENABLE_NET_LOG || UNITY_EDITOR
			NetProtocolHelper.ClientLog(NetMessageId.mail_readMail, "Send->"+"Mail.CS_readMail { "
				+ "mailId="
				+ mailId
				+" }");
#endif
        	UniTask<ReadMailResultData> task = MsgAsyncAwaiter<ReadMailResultData>.Instance.AddMsgAwait();
        	session.SendPack(Pack_for_readMail(mailId));
        	NetProtocolHelper.beginCallRequest?.Invoke(NetMessageId.mail_readMailResult);
			return task;
        }
		
		public static SendPackage Pack_for_readMail(long mailId) 
		{
			SendPackage si_p = NetProtocolHelper.GetSendPackage();
			si_p.Header.Messagid = NetMessageId.mail_readMail;
			si_p.StartWrite();
			SOutputStream _out = si_p.OutputStream;
			_out.Write_long(mailId);
			return si_p;
		}
		/// <summary>
        /// 领取附件
        /// </summary>
    	public UniTask<PickUpResultData> CS_pickUp(List<long> mailIdList)
        {
            return _CS_pickUp(mailIdList);
        }
        
        public UniTask<PickUpResultData> _CS_pickUp(List<long> mailIdList)
        {
        	ISession session = GetSession();
        	if(session == null) return UniTask.FromResult(default(PickUpResultData));
#if ENABLE_NET_LOG || UNITY_EDITOR
			NetProtocolHelper.ClientLog(NetMessageId.mail_pickUp, "Send->"+"Mail.CS_pickUp { "
				+ "mailIdList="
				+ mailIdList.ToString<long>()
				+" }");
#endif
        	UniTask<PickUpResultData> task = MsgAsyncAwaiter<PickUpResultData>.Instance.AddMsgAwait();
        	session.SendPack(Pack_for_pickUp(mailIdList));
        	NetProtocolHelper.beginCallRequest?.Invoke(NetMessageId.mail_pickUpResult);
			return task;
        }
		
		public static SendPackage Pack_for_pickUp(List<long> mailIdList) 
		{
			SendPackage si_p = NetProtocolHelper.GetSendPackage();
			si_p.Header.Messagid = NetMessageId.mail_pickUp;
			si_p.StartWrite();
			SOutputStream _out = si_p.OutputStream;
			_out.Write_list_long(mailIdList);	
			return si_p;
		}
		/// <summary>
        /// 删除邮件
        /// </summary>
    	public UniTask<DeleteMailResultData> CS_deleteMail(List<long> mailIdList)
        {
            return _CS_deleteMail(mailIdList);
        }
        
        public UniTask<DeleteMailResultData> _CS_deleteMail(List<long> mailIdList)
        {
        	ISession session = GetSession();
        	if(session == null) return UniTask.FromResult(default(DeleteMailResultData));
#if ENABLE_NET_LOG || UNITY_EDITOR
			NetProtocolHelper.ClientLog(NetMessageId.mail_deleteMail, "Send->"+"Mail.CS_deleteMail { "
				+ "mailIdList="
				+ mailIdList.ToString<long>()
				+" }");
#endif
        	UniTask<DeleteMailResultData> task = MsgAsyncAwaiter<DeleteMailResultData>.Instance.AddMsgAwait();
        	session.SendPack(Pack_for_deleteMail(mailIdList));
        	NetProtocolHelper.beginCallRequest?.Invoke(NetMessageId.mail_deleteMailResult);
			return task;
        }
		
		public static SendPackage Pack_for_deleteMail(List<long> mailIdList) 
		{
			SendPackage si_p = NetProtocolHelper.GetSendPackage();
			si_p.Header.Messagid = NetMessageId.mail_deleteMail;
			si_p.StartWrite();
			SOutputStream _out = si_p.OutputStream;
			_out.Write_list_long(mailIdList);	
			return si_p;
		}
#endregion
#region Messages
        public struct GetMailsResultData : IReceiveMessage {
        	private int? _code;
        	public int code {get{return _code == null ? -1 : (int)_code;}private set{_code = value;}}
	        public List<MailSimplePOD> mailList;
            public bool IsFail => _code != null && _code != 0;
            public bool IsSuccess =>_code != null && _code == 0;
            public bool IsCanceled => _code == null;
            public void FromPackage(ReceivePackage _package)
            {
                SInputStream _in = _package.InputStream;
                code = _in.HasRemaining() ? _in.Read_int() : default;
                mailList = _in.HasRemaining() ? _in.Read_list_pod<MailSimplePOD>(MailSimplePOD.DynamicFactory) : default;
            }
            
            public int GetMessageId() {return NetMessageId.mail_getMailsResult;}
            
            public override string ToString()
            {
                return "Mail.getMailsResult"+ ", code="+ code+ ", mailList="+ mailList.ToString<MailSimplePOD>();
            }
        }
        public struct ReadMailResultData : IReceiveMessage {
        	private int? _code;
        	public int code {get{return _code == null ? -1 : (int)_code;}private set{_code = value;}}
	        public MailPOD mail;
            public bool IsFail => _code != null && _code != 0;
            public bool IsSuccess =>_code != null && _code == 0;
            public bool IsCanceled => _code == null;
            public void FromPackage(ReceivePackage _package)
            {
                SInputStream _in = _package.InputStream;
                code = _in.HasRemaining() ? _in.Read_int() : default;
                mail = _in.HasRemaining() ? _in.Read_pod<MailPOD>(MailPOD.DynamicFactory) : default;
            }
            
            public int GetMessageId() {return NetMessageId.mail_readMailResult;}
            
            public override string ToString()
            {
                return "Mail.readMailResult"+ ", code="+ code+ ", mail="+ mail;
            }
        }
        public struct PickUpResultData : IReceiveMessage {
        	private int? _code;
        	public int code {get{return _code == null ? -1 : (int)_code;}private set{_code = value;}}
	        public List<long> pickedList;
	        public List<ItemShowPOD> getItems;
            public bool IsFail => _code != null && _code != 0;
            public bool IsSuccess =>_code != null && _code == 0;
            public bool IsCanceled => _code == null;
            public void FromPackage(ReceivePackage _package)
            {
                SInputStream _in = _package.InputStream;
                code = _in.HasRemaining() ? _in.Read_int() : default;
                pickedList = _in.HasRemaining() ? _in.Read_list_long() : default;
                getItems = _in.HasRemaining() ? _in.Read_list_pod<ItemShowPOD>(ItemShowPOD.DynamicFactory) : default;
            }
            
            public int GetMessageId() {return NetMessageId.mail_pickUpResult;}
            
            public override string ToString()
            {
                return "Mail.pickUpResult"+ ", code="+ code+ ", pickedList="+ pickedList.ToString<long>()+ ", getItems="+ getItems.ToString<ItemShowPOD>();
            }
        }
        public struct DeleteMailResultData : IReceiveMessage {
        	private int? _code;
        	public int code {get{return _code == null ? -1 : (int)_code;}private set{_code = value;}}
	        public List<long> deletedList;
            public bool IsFail => _code != null && _code != 0;
            public bool IsSuccess =>_code != null && _code == 0;
            public bool IsCanceled => _code == null;
            public void FromPackage(ReceivePackage _package)
            {
                SInputStream _in = _package.InputStream;
                code = _in.HasRemaining() ? _in.Read_int() : default;
                deletedList = _in.HasRemaining() ? _in.Read_list_long() : default;
            }
            
            public int GetMessageId() {return NetMessageId.mail_deleteMailResult;}
            
            public override string ToString()
            {
                return "Mail.deleteMailResult"+ ", code="+ code+ ", deletedList="+ deletedList.ToString<long>();
            }
        }
        public struct NotifyNewMailData : IReceiveMessage {
	        public int newMailCount;
            public void FromPackage(ReceivePackage _package)
            {
                SInputStream _in = _package.InputStream;
                newMailCount = _in.HasRemaining() ? _in.Read_int() : default;
            }
            
            public int GetMessageId() {return NetMessageId.mail_notifyNewMail;}
            
            public override string ToString()
            {
                return "Mail.notifyNewMail"+ ", newMailCount="+ newMailCount;
            }
        }
    }
#endregion
}